1   /*
2    * Copyright (C) 2011 The Guava Authors
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    * 
7    * http://www.apache.org/licenses/LICENSE-2.0
8    * 
9    * Unless required by applicable law or agreed to in writing, software distributed under the
10   * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11   * express or implied. See the License for the specific language governing permissions and
12   * limitations under the License.
13   */
14  
15  package com.google.common.primitives;
16  
17  import static com.google.common.base.Preconditions.checkArgument;
18  import static com.google.common.base.Preconditions.checkNotNull;
19  import static com.google.common.primitives.UnsignedInts.INT_MASK;
20  import static com.google.common.primitives.UnsignedInts.compare;
21  import static com.google.common.primitives.UnsignedInts.toLong;
22  
23  import com.google.common.annotations.GwtCompatible;
24  
25  import java.math.BigInteger;
26  
27  import javax.annotation.CheckReturnValue;
28  import javax.annotation.Nullable;
29  
30  /**
31   * A wrapper class for unsigned {@code int} values, supporting arithmetic operations.
32   * 
33   * <p>In some cases, when speed is more important than code readability, it may be faster simply to
34   * treat primitive {@code int} values as unsigned, using the methods from {@link UnsignedInts}.
35   * 
36   * <p>See the Guava User Guide article on <a href=
37   * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
38   * unsigned primitive utilities</a>.
39   * 
40   * @author Louis Wasserman
41   * @since 11.0
42   */
43  @GwtCompatible(emulated = true)
44  public final class UnsignedInteger extends Number implements Comparable<UnsignedInteger> {
45    public static final UnsignedInteger ZERO = fromIntBits(0);
46    public static final UnsignedInteger ONE = fromIntBits(1);
47    public static final UnsignedInteger MAX_VALUE = fromIntBits(-1);
48  
49    private final int value;
50  
51    private UnsignedInteger(int value) {
52      // GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
53      this.value = value & 0xffffffff;
54    }
55  
56    /**
57     * Returns an {@code UnsignedInteger} corresponding to a given bit representation.
58     * The argument is interpreted as an unsigned 32-bit value. Specifically, the sign bit
59     * of {@code bits} is interpreted as a normal bit, and all other bits are treated as usual.
60     *
61     * <p>If the argument is nonnegative, the returned result will be equal to {@code bits},
62     * otherwise, the result will be equal to {@code 2^32 + bits}.
63     *
64     * <p>To represent unsigned decimal constants, consider {@link #valueOf(long)} instead.
65     * 
66     * @since 14.0
67     */
68    public static UnsignedInteger fromIntBits(int bits) {
69      return new UnsignedInteger(bits);
70    }
71  
72    /**
73     * Returns an {@code UnsignedInteger} that is equal to {@code value},
74     * if possible.  The inverse operation of {@link #longValue()}.
75     */
76    public static UnsignedInteger valueOf(long value) {
77      checkArgument((value & INT_MASK) == value,
78          "value (%s) is outside the range for an unsigned integer value", value);
79      return fromIntBits((int) value);
80    }
81  
82    /**
83     * Returns a {@code UnsignedInteger} representing the same value as the specified
84     * {@link BigInteger}. This is the inverse operation of {@link #bigIntegerValue()}.
85     * 
86     * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^32}
87     */
88    public static UnsignedInteger valueOf(BigInteger value) {
89      checkNotNull(value);
90      checkArgument(value.signum() >= 0 && value.bitLength() <= Integer.SIZE,
91          "value (%s) is outside the range for an unsigned integer value", value);
92      return fromIntBits(value.intValue());
93    }
94  
95    /**
96     * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
97     * as an unsigned {@code int} value.
98     * 
99     * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
100    *         value
101    */
102   public static UnsignedInteger valueOf(String string) {
103     return valueOf(string, 10);
104   }
105 
106   /**
107    * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
108    * as an unsigned {@code int} value in the specified radix.
109    * 
110    * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
111    *         value
112    */
113   public static UnsignedInteger valueOf(String string, int radix) {
114     return fromIntBits(UnsignedInts.parseUnsignedInt(string, radix));
115   }
116 
117   /**
118    * Returns the result of adding this and {@code val}. If the result would have more than 32 bits,
119    * returns the low 32 bits of the result.
120    * 
121    * @since 14.0
122    */
123   @CheckReturnValue
124   public UnsignedInteger plus(UnsignedInteger val) {
125     return fromIntBits(this.value + checkNotNull(val).value);
126   }
127 
128   /**
129    * Returns the result of subtracting this and {@code val}. If the result would be negative,
130    * returns the low 32 bits of the result.
131    * 
132    * @since 14.0
133    */
134   @CheckReturnValue
135   public UnsignedInteger minus(UnsignedInteger val) {
136     return fromIntBits(value - checkNotNull(val).value);
137   }
138 
139   /**
140    * Returns the result of dividing this by {@code val}.
141    * 
142    * @throws ArithmeticException if {@code val} is zero
143    * @since 14.0
144    */
145   @CheckReturnValue
146   public UnsignedInteger dividedBy(UnsignedInteger val) {
147     return fromIntBits(UnsignedInts.divide(value, checkNotNull(val).value));
148   }
149 
150   /**
151    * Returns this mod {@code val}.
152    * 
153    * @throws ArithmeticException if {@code val} is zero
154    * @since 14.0
155    */
156   @CheckReturnValue
157   public UnsignedInteger mod(UnsignedInteger val) {
158     return fromIntBits(UnsignedInts.remainder(value, checkNotNull(val).value));
159   }
160 
161   /**
162    * Returns the value of this {@code UnsignedInteger} as an {@code int}. This is an inverse
163    * operation to {@link #fromIntBits}.
164    * 
165    * <p>Note that if this {@code UnsignedInteger} holds a value {@code >= 2^31}, the returned value
166    * will be equal to {@code this - 2^32}.
167    */
168   @Override
169   public int intValue() {
170     return value;
171   }
172 
173   /**
174    * Returns the value of this {@code UnsignedInteger} as a {@code long}.
175    */
176   @Override
177   public long longValue() {
178     return toLong(value);
179   }
180 
181   /**
182    * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
183    * primitive conversion from {@code int} to {@code float}, and correctly rounded.
184    */
185   @Override
186   public float floatValue() {
187     return longValue();
188   }
189 
190   /**
191    * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
192    * primitive conversion from {@code int} to {@code double}, and correctly rounded.
193    */
194   @Override
195   public double doubleValue() {
196     return longValue();
197   }
198 
199   /**
200    * Returns the value of this {@code UnsignedInteger} as a {@link BigInteger}.
201    */
202   public BigInteger bigIntegerValue() {
203     return BigInteger.valueOf(longValue());
204   }
205 
206   /**
207    * Compares this unsigned integer to another unsigned integer.
208    * Returns {@code 0} if they are equal, a negative number if {@code this < other},
209    * and a positive number if {@code this > other}.
210    */
211   @Override
212   public int compareTo(UnsignedInteger other) {
213     checkNotNull(other);
214     return compare(value, other.value);
215   }
216 
217   @Override
218   public int hashCode() {
219     return value;
220   }
221 
222   @Override
223   public boolean equals(@Nullable Object obj) {
224     if (obj instanceof UnsignedInteger) {
225       UnsignedInteger other = (UnsignedInteger) obj;
226       return value == other.value;
227     }
228     return false;
229   }
230 
231   /**
232    * Returns a string representation of the {@code UnsignedInteger} value, in base 10.
233    */
234   @Override
235   public String toString() {
236     return toString(10);
237   }
238 
239   /**
240    * Returns a string representation of the {@code UnsignedInteger} value, in base {@code radix}.
241    * If {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix
242    * {@code 10} is used.
243    */
244   public String toString(int radix) {
245     return UnsignedInts.toString(value, radix);
246   }
247 }
248